/* BeerScreen, Copyright (C) 2009-2010  Gabriel Tremblay <initnull@gmail.com>
 * http://www.etrange.ca/beerscreen
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package ca.etrange.beerscreen.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.util.Map;
import java.util.Observable;
import java.util.Observer;

import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;

import ca.etrange.beerscreen.model.Beer;
import ca.etrange.beerscreen.model.Beer.BEER_SPECS;

/**
 * Main display panel for a specific beer.
 * 
 * @author initnull
 * 
 */
public class BeerInfoPanel extends AbstractTranslucidPanel implements Observer {
	// general widget prop
	private static final long serialVersionUID = 1L;

	// Components
	private JLabel beerNameLabel;
	private JLabel emptyBeerLabel;
	private JTable beerSpecs;
	private final KegWidget kegLevelWidget;
	private JLabel tapHandleNumber;

	private final Map<BEER_SPECS, String> specs;
	private TableModel twoColModel;

	// Model
	private final Beer beer;

	public BeerInfoPanel(final Beer beer) {
		this.beer = beer;
		beer.addObserver(this);
		kegLevelWidget = new KegWidget(beer);
		this.specs = beer.getAllSpecs();
		this.layoutComponents();
		
		// watch the model
		beer.addObserver(this); 
		this.update(beer, null);
	}

	// Lay out all the components pane to the screen
	private void layoutComponents() {
		// Main layout is a borderlayout.
		// Page start contains the name of the beer
		// Center contains the beer specs
		// Page end contains the keg level and tap identification
		// Line start and line end are used for spacing purposes.
		final BorderLayout borderLayout = new BorderLayout();
		this.setLayout(borderLayout);

		/** Top panel **/
		final JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
		topPanel.setOpaque(false);
		beerNameLabel = new JLabel();
		beerNameLabel.setFont(new Font("Helvetica", Font.BOLD, 24));
		beerNameLabel.setForeground(Color.WHITE);
		topPanel.add(beerNameLabel);
		topPanel.add(new JSeparator(JSeparator.HORIZONTAL));

		/** Center panel **/
		final JPanel centerPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
		centerPanel.setOpaque(false);

		// create table
		beerSpecs = new TransparentJTable();
		
		// Generate a tableModel
		twoColModel = new DefaultTableModel(specs.size(), 2);
		beerSpecs.setModel(twoColModel);

		// Set text allign
		beerSpecs.setDefaultRenderer(Object.class, new SpreadTextCellRenderer());
		centerPanel.add(beerSpecs);

		/** bottom panel **/
		final JPanel bottomPanel = new JPanel();
		bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));
		bottomPanel.setOpaque(false);
		bottomPanel.add(kegLevelWidget);

		tapHandleNumber = new JLabel();
		tapHandleNumber.setFont(new Font("Helvetica", Font.BOLD, 56));
		tapHandleNumber.setForeground(Color.WHITE);
		tapHandleNumber.setText(String.valueOf(beer.getBeerIndex()));
		tapHandleNumber.setAlignmentX(CENTER_ALIGNMENT);
		bottomPanel.add(tapHandleNumber);

		// Add panels to main layout
		this.add(topPanel, BorderLayout.PAGE_START);
		this.add(centerPanel, BorderLayout.CENTER);
		this.add(bottomPanel, BorderLayout.PAGE_END);
	}

	@Override
	public void update(Observable observable, Object argument) {
		// We only want to update this observer on beer model changes.
		if (observable.getClass() != Beer.class) {
			return;
		}
		
		// Get the beer.
		final Beer beer = (Beer) observable;
		// Set fields value
		beerNameLabel.setText(beer.getBeerName());
		
		// Add specs to table model
		int row = 0;
		for(final BEER_SPECS spec : BEER_SPECS.values()){
			twoColModel.setValueAt(spec.getDisplayValue(), row, 0);
			
			// Test for value presence
			final String currentSpec = specs.get(spec);
			if(currentSpec.trim().isEmpty()){
				twoColModel.setValueAt("unavailable", row, 1);
			} else {
				twoColModel.setValueAt(specs.get(spec), row, 1);
			}
			row++;
		}
	}
}
